package com.charge.app.utils;

import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.tea.TeaException;
import com.charge.app.SpringBean;
import com.charge.app.entity.CbSmsSendLog;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class SmsMsgFromAliyun {

	@Value("${aliyun.sms.mode}")
	private String mode;

	@Value("${aliyun.sms.accessKeyId}")
	private String accessKeyId;

	@Value("${aliyun.sms.accessKeySecret}")
	private String accessKeySecret;

	@Value("${aliyun.verification-code.signName}")
	private String vcSignName;

	@Value("${aliyun.verification-code.templateCode}")
	private String vcTemplateCode;

	private Client smsClient;

	public static final String PROD_MODE = "prod";
	public static final String RET_SUCCESS = "isSuccess";
	public static final String RET_CODE = "code";
	public static final String RET_MSG = "msg";

	public static final String cacheName = "SmsConfig";
	public static final String KeyMode = "Mode";
	public static final String KeyAccessKey = "AccessKey";
	public static final String KeySecretKey = "SecretKey";
	public static final String KeySignName = "SignName";
	public static final String KeyTemplateCode = "TemplateCode";
	
	/**
	 * 使用AK&SK初始化账号Client
	 * 
	 * @param accessKeyId
	 * @param accessKeySecret
	 * @return Client
	 * @throws Exception
	 */
	public Client getClient(String accessKeyId, String accessKeySecret) throws Exception {
		if (smsClient == null) {
			com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
					// 必填，您的 AccessKey ID
					.setAccessKeyId(accessKeyId)
					// 必填，您的 AccessKey Secret
					.setAccessKeySecret(accessKeySecret);
			// 访问的域名
			config.endpoint = "dysmsapi.aliyuncs.com";
			smsClient = new Client(config);
		}
		return smsClient;
	}

	public Client createClient() throws Exception {
		String accessKeyId2 = (String) SpringBean.bean.redisUtils.get(cacheName, KeyAccessKey);
		if (StringUtils.isBlank(accessKeyId2)) {
			accessKeyId2 = accessKeyId;
		}
		String accessKeySecret2 = (String) SpringBean.bean.redisUtils.get(cacheName, KeySecretKey);
		if (StringUtils.isBlank(accessKeySecret2)) {
			accessKeySecret2 = accessKeySecret;
		}
		return getClient(accessKeyId2, accessKeySecret2);
	}

	/**
	 * 发送短信验证码
	 * @param phoneNumbers
	 * @param code
	 * @return {Code:请求状态码。返回OK代表请求成功。其他错误码，请参见API错误码。Message:状态码的描述。eg:OK。BizId:发送回执ID。可根据发送回执ID在接口QuerySendDetails中查询具体的发送状态。RequestId:请求ID。}
	 */
	public Map<String, Object> sendSms4Code(String phoneNumbers, String code) {
		String templateParam = "{\"code\":\"" + code + "\"}";
		return this.sendAliyunSms(phoneNumbers, vcSignName, vcTemplateCode, templateParam);
	}
	
	/**
	 * 占位费预警提醒<br>
	 * 温馨提示：您好！当前是充电高峰期，您的车辆${plate}已占位${number}分钟，请尽快挪车，感谢您的理解和配合。如已挪车请忽略。电站名称：${stationName}
	 * @param phoneNumbers 接收短信手机号
	 * @param plate
	 * @param number
	 * @param stationName
	 * @return
	 */
	public Map<String, Object> sendSms4OccupyPlaceTodo(String phoneNumbers, String plate, String number, String stationName) {
		String templateParam = "{\"plate\":\"" + plate + "\", \"number\": \"" + number + "\", \"stationName\": \"" + stationName + "\" }";
		return this.sendAliyunSms(phoneNumbers, vcSignName, "SMS_463525069", templateParam);
	}
	
	/**
	 * 已产生占位费提醒<br>
	 * 温馨提示：您好！当前是充电高峰期，您的车辆${plate}已占位超过${number}分钟，平台已开始计费，感谢您的理解和配合。电站名称：${stationName}
	 * @param phoneNumbers 接收短信手机号
	 * @param plate
	 * @param number
	 * @param stationName
	 * @return
	 */
	public Map<String, Object> sendSms4OccupyPlaceDone(String phoneNumbers, String plate, String number, String stationName) {
		String templateParam = "{\"plate\":\"" + plate + "\", \"number\": \"" + number + "\", \"stationName\": \"" + stationName + "\" }";
		return this.sendAliyunSms(phoneNumbers, vcSignName, "SMS_463515078", templateParam);
	}
	
	/**
	 * 未结算订单<br>
	 * 您好！您的车辆${plate}已结束充电，请及时将充电枪归位并支付结算，感谢您的支持与信任！电站名称：${stationName}。
	 * @param phoneNumbers 接收短信手机号
	 * @param plate
	 * @param stationName
	 * @return
	 */
	public Map<String, Object> sendSms4OrderTodo(String phoneNumbers, String plate, String stationName) {
		String templateParam = "{\"plate\":\"" + plate + "\", \"stationName\": \"" + stationName + "\" }";
		return this.sendAliyunSms(phoneNumbers, vcSignName, "SMS_463490070", templateParam);
	}
	
	/**
	 * 已结算订单<br>
	 * 您好！您的车辆${plate}本次消费共${money}元，系统自动结算完成。感谢您的支持与信任！电站名称：${stationName}。
	 * @param phoneNumbers 接收短信手机号
	 * @param plate
	 * @param money
	 * @param stationName
	 * @return
	 */
	public Map<String, Object> sendSms4OrderDone(String phoneNumbers, String plate, double money, String stationName) {
		String templateParam = "{\"plate\":\"" + plate + "\", \"money\": \"" + money + "\", \"stationName\": \"" + stationName + "\" }";
		return this.sendAliyunSms(phoneNumbers, vcSignName, "SMS_463550069", templateParam);
	}
	
	/**
	 * 
	 * @param phoneNumbers
	 * @param signName
	 * @param templateCode
	 * @param templateParam JSON字符串
	 * @return
	 */
	public Map<String, Object> sendAliyunSms(String phoneNumbers, String signName, String templateCode, String templateParam) {
		Map<String, Object> res = new HashMap<String, Object>();
		res.put(RET_SUCCESS, false);
		res.put(RET_CODE, "-1");

		CbSmsSendLog sendlog = new CbSmsSendLog();
		sendlog.setPhoneNumbers(phoneNumbers);
		sendlog.setDelFlag("0");
		sendlog.setCreateDate(Calendar.getInstance().getTime());
		sendlog.setUpdateDate(sendlog.getCreateDate());
		sendlog.setCreateBy("app");
		sendlog.setUpdateBy("app");
		try {
			// String mode2 = (String) SpringBean.bean.redisUtils.get(cacheName, KeyMode);
			// if (StringUtils.isBlank(mode2)) {
			// mode2 = mode;
			// }
			if (!PROD_MODE.equals(mode)) {
				res.put(RET_SUCCESS, true);
				res.put(RET_CODE, "OK");
				res.put(RET_MSG, "no prod mode!");
				return res;
			}

			Client client = createClient();
			if (client == null) {
				res.put(RET_SUCCESS, false);
				res.put(RET_CODE, "err");
				res.put(RET_MSG, "AccessKeyId, AccessKeySecret参数可能存在问题!");
				return res;
			}

			sendlog.setSignName(signName);
			sendlog.setTemplateCode(templateCode);

			SendSmsRequest sendSmsRequest = new SendSmsRequest().setPhoneNumbers(phoneNumbers).setSignName(signName).setTemplateCode(templateCode)
					.setTemplateParam(templateParam);
			sendlog.setTemplateParam(templateParam);

			com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();

			// 复制代码运行请自行打印 API 的返回值
			SendSmsResponse rsp = client.sendSmsWithOptions(sendSmsRequest, runtime);
			// log.info(rsp.getBody().getCode()); // isv.BUSINESS_LIMIT_CONTROL
			// 触发分钟级流控Permits:1
			log.info("code:{}, Message:{}, BizId:{}, RequestId:{}", rsp.getBody().getCode(), rsp.getBody().getMessage(), rsp.getBody().getBizId(),
					rsp.getBody().getRequestId());

			res.put(RET_SUCCESS, "OK".equals(rsp.getBody().getCode()));
			res.put(RET_CODE, rsp.getBody().getCode());
			res.put(RET_MSG, rsp.getBody().getMessage());
			res.put("bizId", rsp.getBody().getBizId());
			res.put("requestId", rsp.getBody().getRequestId());
			return res;
		} catch (TeaException error) {
			log.error(error.getMessage());
			error.printStackTrace();
			res.put(RET_MSG, error.getMessage());
			sendlog.setRetBody(error.getMessage());
		} catch (Exception _error) {
			log.error(_error.getMessage());
			_error.printStackTrace();
			res.put(RET_MSG, _error.getMessage());
			sendlog.setRetBody(_error.getMessage());
		} finally {
			sendlog.setRetCode(String.valueOf(res.get(RET_SUCCESS)));
			sendlog.setRetBody(res.toString());
			try {
				SpringBean.bean.getCbSmsSendLogService().add(sendlog);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		return res;
	}

	public static void main(String[] args_) throws Exception {
		// java.util.List<String> args = java.util.Arrays.asList(args_);
		// 工程代码泄露可能会导致AccessKey泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议使用更安全的 STS
		// 方式，更多鉴权访问方式请参见：https://help.aliyun.com/document_detail/378657.html
		String accessKeyId = "LTAI5tPUvuUuWvMSk65xep2o", accessKeySecret = "x3u1IiHEeVKnsAIJcCUYYH1w6YGOj0";
		Client client = new SmsMsgFromAliyun().getClient(accessKeyId, accessKeySecret);

		try {
			String plate = "湘A000000", number = "25", stationName = "昌茂未来城充电站";
			double  money = 123.23;
			String templateParam = "{\"plate\":\"" + plate + "\", \"number\": \"" + number + "\", \"stationName\": \"" + stationName + "\" }";

//			String templateParam = "{\"plate\":\"" + plate + "\", \"stationName\": \"" + stationName + "\" }";
//			return this.sendAliyunSms(phoneNumbers, vcSignName, "SMS_463490070", templateParam);
			
			templateParam = "{\"plate\":\"" + plate + "\", \"money\": \"" + money + "\", \"stationName\": \"" + stationName + "\" }";
//			return this.sendAliyunSms(phoneNumbers, vcSignName, "SMS_463550069", templateParam);
			
			SendSmsRequest sendSmsRequest = new SendSmsRequest().setPhoneNumbers("18600049527").setSignName("一止充")
					.setTemplateCode("SMS_463550069").setTemplateParam(templateParam);

			com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();

			// 复制代码运行请自行打印 API 的返回值
			SendSmsResponse rsp = client.sendSmsWithOptions(sendSmsRequest, runtime);
			System.out.println(rsp.getBody().getCode());
			System.out.println(rsp.getBody().getMessage());
			System.out.println(rsp.getBody().getBizId());
			System.out.println(rsp.getBody().getRequestId());
		} catch (TeaException error) {
			// 如有需要，请打印 error
			com.aliyun.teautil.Common.assertAsString(error.message);
		} catch (Exception _error) {
			TeaException error = new TeaException(_error.getMessage(), _error);
			// 如有需要，请打印 error
			com.aliyun.teautil.Common.assertAsString(error.message);
		}
	}
}
